package models

import (
	password2 "SlowAdmin/pkg/password"
	"errors"
	"github.com/beego/beego/v2/core/logs"
	"gorm.io/gorm/clause"
	"strings"
	"time"
)

type AdminUser struct {
	Id        uint        `json:"id"`
	Username  string      `json:"username"`
	Password  string      `json:"password"`
	Name      string      `json:"name"`
	AvatarId  uint        `json:"avatar_id"`
	Roles     []AdminRole `json:"roles" gorm:"many2many:admin_user_role"`
	CreatedAt time.Time   `json:"created_at"`
	UpdatedAt time.Time   `json:"-"`
}

// 登录
func (a *AdminUser) Login(username, password string) (AdminUser, bool) {
	user := AdminUser{}

	err := Db.Model(AdminUser{}).Preload("Roles.Menus").Where("username = ?", username).First(&user).Error

	if err != nil {
		logs.Error(err)
		return user, false
	}

	if password2.CheckHash(password, user.Password) == true {
		return user, true
	}

	return user, false
}

// @title 获取用户角色信息
func (a *AdminUser) RoleInfo() []map[string]interface{} {
	var data []map[string]interface{}
	if a.IsSuperAdmin() {
		Db.Model(AdminMenu{}).
			Order("`order` desc").
			Select([]string{"id", "parent_id", "label", "router", "href", "path", "key", "icon_library", "icon", "show"}).
			Find(&data)
	} else {
		var menuIds []uint

		for _, item := range a.Roles {
			for _, menu := range item.Menus {
				menuIds = append(menuIds, menu.Id)
			}
		}

		Db.Model(AdminMenu{}).
			Order("`order` desc").
			Select([]string{"id", "parent_id", "label", "router", "href", "path", "key", "icon_library", "icon", "show"}).
			Where("id in ?", menuIds).
			Find(&data)
	}

	return data
}

// @title 用户角色信息 - 树结构
func (a *AdminUser) RoleTree() []map[string]interface{} {
	return treeHandler(a.RoleInfo(), 0)
}

// @title 是否是超级管理员
func (a *AdminUser) IsSuperAdmin() bool {
	for _, item := range a.Roles {
		if item.Slug == "administrator" {
			return true
		}
	}

	return false
}

// @title 数据校验
func (a *AdminUser) validate() error {
	if a.Username == "" {
		return errors.New("用户名不能为空")
	}

	if a.Password == "" {
		return errors.New("密码不能为空")
	}

	var count int64
	Db.Model(a).Where("username = ?", a.Username).Where("id <> ?", a.Id).Count(&count)

	if count > 0 {
		return errors.New("登录账号已存在")
	}

	return nil
}

// @title 添加
func (a *AdminUser) Store() error {
	err := a.validate()

	if err != nil {
		return err
	}

	a.Id = 0

	res := Db.Omit(clause.Associations).Create(a)

	a.handleAssociations()

	return res.Error
}

// @title 获取列表
func (a *AdminUser) GetList(page, pageSize int) ([]map[string]interface{}, int64) {
	var list []AdminUser
	var total int64

	Db.Model(a).Count(&total)
	Db.Preload("Roles").Limit(pageSize).Offset((page - 1) * pageSize).Order("updated_at desc").Find(&list)

	data := DateTimeFormatList(list, []string{"created_at"})

	return data, total
}

// @title 获取单条数据
func (a *AdminUser) GetOne(id string) AdminUser {
	var data AdminUser

	Db.Model(a).Preload("Roles").Where("id = ?", id).First(&data)

	return data
}

// @title 更新
func (a *AdminUser) Update() error {
	err := a.validate()

	if err != nil {
		return err
	}

	a.handleAssociations()

	return Db.Omit(clause.Associations).Save(a).Error
}

// @title 处理关联关系
func (a *AdminUser) handleAssociations() {
	var userRole []map[string]interface{}

	for _, item := range a.Roles {
		userRole = append(userRole, map[string]interface{}{
			"admin_user_id": a.Id,
			"admin_role_id": item.Id,
		})
	}

	Db.Table("admin_user_role").Where("admin_user_id = ?", a.Id).Delete(nil)

	if len(userRole) > 0 {
		Db.Table("admin_user_role").Create(userRole)
	}
}

// @title 删除
func (a *AdminUser) Delete(ids string) error {
	res := Db.Delete(AdminUser{}, "id in (?)", strings.Split(ids, ","))

	if res.Error != nil {
		logs.Error(res.Error.Error())
		return res.Error
	}

	return nil
}

